package sv.gob.mh.dgii.ssc.controller.configuration;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import sv.gob.mh.dgii.common.PagedResult;
import sv.gob.mh.dgii.common.Utils;
import sv.gob.mh.dgii.dao.hibernate.Dao;

public class BasicTableView implements Serializable {

    private final static Log log = LogFactory.getLog(BasicTableView.class);
    public final static String DIR_ASC = "asc";
    public final static String DIR_DESC = "desc";
    private String direction = "asc";
    private String sortProperty;
    private int allCounter = 0;
    private int recordsToView = 5;
    private int currentPage = 1;
    private List listado;
    // criteria
    private List<Map<String, Object>> criterions;
    private Map<String, Object> criteria;

    public BasicTableView() {
        criterions = new ArrayList<Map<String, Object>>();
        criteria = new HashMap<String, Object>();
    }

    public BasicTableView(List listado) {
        this.listado = listado;
    }

    public void setOrderByPaginator() {
        if (this.direction == null || (this.direction != null && this.direction.equals(DIR_DESC))) {
            this.direction = DIR_ASC;
        } else {
            this.direction = DIR_DESC;
        }
    }

    public void paginate(Integer page, String sortProperty, Integer switchOrder) {
        if (!Utils.isNullOrEmptyOrZero(switchOrder)) {
            setOrderByPaginator();
        }
        if (!Utils.isNullOrEmptyOrZero(page)) {
            setCurrentPage(page);
        } else if ((page == null || page <= 0) && getCurrentPage() <= 0) {
            setCurrentPage(1);
            log.warn("page changed to 1 cause:"+getCurrentPage());
        }
        if (!Utils.isNullOrEmpty(sortProperty)) {
            setSortProperty(sortProperty);
        }
    }

    public long getPaginationRes() {
        long ret = 0;
        if ((allCounter % recordsToView) != 0) {
            ret = ((allCounter - (allCounter % recordsToView)) / recordsToView) + 1;
        } else {
            ret = allCounter / recordsToView;
        }
        return ret;
    }

    public void clearCriteria() {
        getCriteria().clear();
        getCriterions().clear();
    }

    private void clearCriterions() {
        getCriterions().clear();
    }

    public boolean isEmptyCriteria() {
        return getCriteria().size() == 0;
    }

    public void addCriteria(String key, Object value) {
        getCriteria().put(key, value);
    }

    public void removeCriteria(String key) {
        getCriteria().remove(key);
    }

    public void getCriteria(String key) {
        getCriteria().get(key);
    }

    public PagedResult getPagedResult(Dao dao) {
        return getPagedResult(dao, getCurrentPage(), getRecordsToView());
    }
    public PagedResult fillList(Dao dao) {
        return getPagedResult(dao);
    }

    public PagedResult getPagedResult(Dao dao, Object sample) {
        return getPagedResult(dao, getCurrentPage(), getRecordsToView(), sample);
    }
    public PagedResult fillList(Dao dao, Object sample) {
        return getPagedResult(dao, sample);
    }

    public PagedResult getAllResult(Dao dao) {
        return getPagedResult(dao, -1, -1);
    }

    public PagedResult getPagedResult(Dao dao, int page, int size) {
        PagedResult result = null;
        try {
            if (dao != null) {
                // validate if has criterion 
                clearCriterions();
                if (getCriteria() != null && getCriteria().size() > 0) {
                    getCriterions().add(getCriteria());
                }
                // continue with dao.getPagedResult method
                result = dao.getPage(page, size, getSortProperty(), getDirection(), getCriterions());
                if (result != null) {
                    setListado(result.getList());
                    setAllCounter(result.getCounter());
                }
            }
        } catch (Exception e) {
            log.error(this, e);
        }
        return result;
    }

    public PagedResult getPagedResult(Dao dao, int page, int size, Object sample) {
        PagedResult result = null;
        try {
            if (dao != null) {
                // validate if has criterion 
                clearCriterions();
                if (getCriteria() != null && getCriteria().size() > 0) {
                    getCriterions().add(getCriteria());
                }
                // continue with dao.getPagedResult method
                result = dao.getPage(page, size, getSortProperty(), getDirection(), sample);
                if (result != null) {
                    setListado(result.getList());
                    setAllCounter(result.getCounter());
                }
            }
        } catch (Exception e) {
            log.error(this, e);
        }
        return result;
    }

    public void setAscendingDirection() {
        setDirection(BasicTableView.DIR_ASC);
    }

    public void setDescendingDirection() {
        setDirection(BasicTableView.DIR_DESC);
    }

    /**
     * @return the direction
     */
    public String getDirection() {
        return direction;
    }

    /**
     * @param direction the direction to set
     */
    public void setDirection(String direction) {
        this.direction = direction;
    }

    /**
     * @return the sortProperty
     */
    public String getSortProperty() {
        return sortProperty;
    }

    /**
     * @param sortProperty the sortProperty to set
     */
    public void setSortProperty(String sortProperty) {
        this.sortProperty = sortProperty;
    }

    /**
     * @return the allCounter
     */
    public int getAllCounter() {
        return allCounter;
    }

    /**
     * @param allCounter the allCounter to set
     */
    public void setAllCounter(int allCounter) {
        this.allCounter = allCounter;
    }

    /**
     * @return the recordsToView
     */
    public int getRecordsToView() {
        return recordsToView;
    }

    /**
     * @param recordsToView the recordsToView to set
     */
    public void setRecordsToView(int recordsToView) {
        this.recordsToView = recordsToView;
    }

    /**
     * @return the currentPage
     */
    public int getCurrentPage() {
        return currentPage;
    }

    /**
     * @param currentPage the currentPage to set
     */
    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    /**
     * @return the listado
     */
    public List getListado() {
        return listado;
    }

    /**
     * @param listado the listado to set
     */
    public void setListado(List listado) {
        this.listado = listado;
    }

    /**
     * @return the listado
     */
    public List getList() {
        return listado;
    }

    /**
     * @param list the listado to set
     */
    public void setList(List list) {
        this.listado = list;
    }

    /**
     * @return the criterions
     */
    private List<Map<String, Object>> getCriterions() {
        if (criterions == null) {
            criterions = new ArrayList<Map<String, Object>>();
        }
        return criterions;
    }

    /**
     * @return the criteria
     */
    public Map<String, Object> getCriteria() {
        if (criteria == null) {
            criteria = new HashMap<String, Object>();
        }
        return criteria;
    }

    /**
     * @param criteria the criteria to set
     */
    public void setCriteria(Map<String, Object> criteria) {
        this.criteria = criteria;
    }
}
